package com.lianrui.core;

import java.lang.reflect.ParameterizedType;

import javax.persistence.Table;

import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.jdbc.SQL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.lianrui.commons.Page;
import com.lianrui.commons.exception.BusinessException;
import com.lianrui.commons.exception.SystemException;
import com.lianrui.message.ISystemMessage;

public abstract class AbstractSqlProvider<P extends Page<D>, D extends Domain<T>, T> {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSqlProvider.class);
	
	private Class<D> domainType;
	
	public String add(D d) throws BusinessException {
		return null;
	}

	@SuppressWarnings("unchecked")
	public String delete(final T... id) throws BusinessException {
		return new SQL() {
			{
				DELETE_FROM(getTableName());
				WHERE("where id in (" + StringUtils.join(id) + ")");
			}
		}.toString();
	}

	public String update(D d) throws BusinessException {
		return null;
	}

	public String unique(T id) throws BusinessException {
		return pure(id);
	}

	@SuppressWarnings("unchecked")
	public String get(final T... id) throws BusinessException {
		return new SQL() {
			{
				SELECT("*");
				FROM(getTableName());
				WHERE(" id in (" + StringUtils.join(id) + ")");
			}
		}.toString();
	}

	public String list(final P page) throws BusinessException {
		return new SQL(){
			{
				SELECT("*");
				FROM(getTableName());
				ORDER_BY(page.getOrderBy());
			}
		}.toString();
	}

	public String count(final P page) throws BusinessException {
		return null;
	}

	public String pure(final T id) throws BusinessException {
		return new SQL() {
			{
				SELECT("*");
				FROM(getTableName());
				WHERE(" id = " + id);
			}
		}.toString();
	}

	public Class<D> getDomainType() {
		if (domainType == null) {
			handleDomainType();
		}
		return domainType;
	}

	/**
	 * 功能描述：获取Domain接口类型
	 * @throws BusinessException
	 */
	@SuppressWarnings("unchecked")
	protected void handleDomainType() {
		try {
			domainType = (Class<D>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
		} catch (Throwable e) {
			throw new SystemException(ISystemMessage.SYS_CLASS_INSTANCE_FAILED, LOGGER, getClass(), e);
		}
	}
	
	/**
	 * 功能说明：获取表名
	 * @return
	 * @throws BusinessException
	 */
	public String getTableName() {
		String tableName = "";
		try {
			Table table = getDomainType().getAnnotation(Table.class);
			tableName = table.name();
		} catch (Throwable e) {
			throw new SystemException(ISystemMessage.SYS_LOAD_PROP_FAILED, LOGGER, "Table-Name");
		}
		return tableName;
	}
	
}
